//
//  HelloWorldLayer.m
//  SpaceShooter
//
//  Created by admin on 3/23/12.
//  Copyright __MyCompanyName__ 2012. All rights reserved.
//


// Import the interfaces
#import "HelloWorldLayer.h"
#import "CCParallaxNode-Extras.h"
#import "SimpleAudioEngine.h"


// HelloWorldLayer implementation
@implementation HelloWorldLayer

#define kNumAsteroids   15
#define kNumLasers      5
#define TAG_EFFECT_NODE 0

+(CCScene *) scene
{
	// 'scene' is an autorelease object.
	CCScene *scene = [CCScene node];
	
	// 'layer' is an autorelease object.
	HelloWorldLayer *layer = [HelloWorldLayer node];
	
	// add layer as a child to scene
	[scene addChild: layer];
	
	// return the scene
	return scene;
}

- (void)addEnemy
{
    enemy = [Monster spriteWithSpriteFrameName:@"enemy_spaceship.png"] ;
    enemy.batchNode = _batchNode;
    CGSize winSize = [[CCDirector sharedDirector] winSize];
    enemy.position = ccp(winSize.width * 0.8, winSize.height * 0.5);
    [_batchNode addChild:enemy];
}


- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration {
    
#define kFilteringFactor 0.1
#define kRestAccelX -0.6
#define kShipMaxPointsPerSec (winSize.height*0.5)        
#define kMaxDiffX 0.2
    
    UIAccelerationValue rollingX, rollingY, rollingZ;
    
    rollingX = (acceleration.x * kFilteringFactor) + (rollingX * (1.0 - kFilteringFactor));    
    rollingY = (acceleration.y * kFilteringFactor) + (rollingY * (1.0 - kFilteringFactor));    
    rollingZ = (acceleration.z * kFilteringFactor) + (rollingZ * (1.0 - kFilteringFactor));
    
    float accelX = acceleration.x - rollingX;
    float accelY = acceleration.y - rollingY;
    float accelZ = acceleration.z - rollingZ;
    
    CGSize winSize = [CCDirector sharedDirector].winSize;
    
    float accelDiff = accelX - kRestAccelX;
    float accelFraction = accelDiff / kMaxDiffX;
    float pointsPerSec = kShipMaxPointsPerSec * accelFraction;
    
    _shipPointsPerSecY = pointsPerSec;
    
    
    
}

- (float)randomValueBetween:(float)low andValue:(float)high {
    return (((float) arc4random() / 0xFFFFFFFFu) * (high - low)) + low;
}
// Add new methods above update
- (void)restartTapped:(id)sender {
    [[CCDirector sharedDirector] replaceScene:[CCTransitionZoomFlipX transitionWithDuration:0.5 scene:[HelloWorldLayer scene]]];   
}

- (void)endScene:(EndReason)endReason {
    
    if (_gameOver) return;
    _gameOver = true;
    
    CGSize winSize = [CCDirector sharedDirector].winSize;
    
    NSString *message;
    if (endReason == kEndReasonWin) {
        message = @"You win!";
    } else if (endReason == kEndReasonLose) {
        message = @"You lose!";
    }
    
    CCLabelBMFont *label;
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
        label = [CCLabelBMFont labelWithString:message fntFile:@"Arial-hd.fnt"];
    } else {
        label = [CCLabelBMFont labelWithString:message fntFile:@"Arial.fnt"];
    }
    label.scale = 0.1;
    label.position = ccp(winSize.width/2, winSize.height * 0.6);
    [self addChild:label];
    
    CCLabelBMFont *restartLabel;
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
        restartLabel = [CCLabelBMFont labelWithString:@"Restart" fntFile:@"Arial-hd.fnt"];    
    } else {
        restartLabel = [CCLabelBMFont labelWithString:@"Restart" fntFile:@"Arial.fnt"];    
    }
    
    CCMenuItemLabel *restartItem = [CCMenuItemLabel itemWithLabel:restartLabel target:self selector:@selector(restartTapped:)];
    restartItem.scale = 0.1;
    restartItem.position = ccp(winSize.width/2, winSize.height * 0.4);
    
    CCMenu *menu = [CCMenu menuWithItems:restartItem, nil];
    menu.position = CGPointZero;
    [self addChild:menu];
    
    [restartItem runAction:[CCScaleTo actionWithDuration:0.5 scale:1.0]];
    [label runAction:[CCScaleTo actionWithDuration:0.5 scale:1.0]];
    
}
- (void)setInvisible:(CCNode *)node {
    node.visible = NO;
}
-(CCParticleFire*) getParticleFireEffect {
	return [CCParticleFire node];
}
- (void)addEffect:(CGPoint)xy
{    
    CCNode *node = [self getChildByTag:TAG_EFFECT_NODE];
	[node stopAllActions];
	[self removeChild:node cleanup:YES];

	node = [self getParticleFireEffect];
	[self addChild:node z:1 tag:TAG_EFFECT_NODE];
	
	[node setPosition:xy];

}

-(void)addExplosion:(CGPoint)xy
{
    CCParticleSystemQuad *particle = [CCParticleSystemQuad particleWithFile:@"Explosion.plist"];
    particle.position = xy;
    [self addChild:particle z:20];
    particle.autoRemoveOnFinish = YES;
}
- (void)update:(ccTime)dt {
    
    //Update Position Background
    CGPoint backgroundScrollVel = ccp(-1000, 0);
    _backgroundNode.position = ccpAdd(_backgroundNode.position, ccpMult(backgroundScrollVel, dt));
    
    // Loop Background
    NSArray *spaceDusts = [NSArray arrayWithObjects:_spacedust1, _spacedust2, nil];
    for (CCSprite *spaceDust in spaceDusts) {
        if ([_backgroundNode convertToWorldSpace:spaceDust.position].x < -spaceDust.contentSize.width) {
            [_backgroundNode incrementOffset:ccp(2*spaceDust.contentSize.width,0) forChild:spaceDust];
        }
    }
    
    NSArray *backgrounds = [NSArray arrayWithObjects:_planetsunrise, _galaxy, _spacialanomaly, _spacialanomaly2, nil];
    for (CCSprite *background in backgrounds) {
        if ([_backgroundNode convertToWorldSpace:background.position].x < -background.contentSize.width) {
            [_backgroundNode incrementOffset:ccp(2000,0) forChild:background];
        }
    }
    
    CGSize winSize = [CCDirector sharedDirector].winSize;
    //Adding Asteroids
    double curTime = CACurrentMediaTime();
    if (curTime > _nextAsteroidSpawn) {
        
        float randSecs = [self randomValueBetween:0.20 andValue:1.0];
        _nextAsteroidSpawn = randSecs + curTime;
        
        float randY = [self randomValueBetween:0.0 andValue:winSize.height];
        float randDuration = [self randomValueBetween:2.0 andValue:10.0];
        
        CCSprite *asteroid = [_asteroids objectAtIndex:_nextAsteroid];
        _nextAsteroid++;
        if (_nextAsteroid >= _asteroids.count) _nextAsteroid = 0;
        
        [asteroid stopAllActions];
        asteroid.position = ccp(winSize.width+asteroid.contentSize.width/2, randY);
        asteroid.visible = YES;
        [asteroid runAction:[CCSequence actions:
                             [CCMoveBy actionWithDuration:randDuration position:ccp(-winSize.width-asteroid.contentSize.width, 0)],
                             [CCCallFuncN actionWithTarget:self selector:@selector(setInvisible:)],
                             nil]];
        
    }

    
    //Moving the Ship with the Accelerometer
    
    float maxY = winSize.height - _ship.contentSize.height/2;
    float minY = _ship.contentSize.height/2;
    
    float newY = _ship.position.y + (_shipPointsPerSecY * dt);
    newY = MIN(MAX(newY, minY), maxY);
    _ship.position = ccp(_ship.position.x, newY);
    
    //Basic Collision Detection
    for (CCSprite *asteroid in _asteroids) {        
        if (!asteroid.visible) continue;
        
        for (CCSprite *shipLaser in _shipLasers) {                        
            if (!shipLaser.visible) continue;
            
            if (CGRectIntersectsRect(shipLaser.boundingBox, asteroid.boundingBox)) {                
                shipLaser.visible = NO;
                asteroid.visible = NO;
                _ship.score++;
                [[SimpleAudioEngine sharedEngine] playEffect:@"explosion_large.caf"];
                
                [self addExplosion:asteroid.position];
 //               [self addEffect:asteroid.position];
                
                continue;
            }
            if (CGRectIntersectsRect(shipLaser.boundingBox, enemy.boundingBox)) {                
                shipLaser.visible = NO; 
                enemy.hp--;
                [[SimpleAudioEngine sharedEngine] playEffect:@"explosion_small.caf"];
                continue;
            }

        }
        
        if (CGRectIntersectsRect(_ship.boundingBox, asteroid.boundingBox)) {
            asteroid.visible = NO;
            [_ship runAction:[CCBlink actionWithDuration:1.0 blinks:9]];            
            _ship.hp--;
        }
    }
    for (CCSprite* laser in enemy.shipLasers)
    {
        if (CGRectIntersectsRect(_ship.boundingBox,laser.boundingBox))
            {
                laser.visible = NO;
                [[SimpleAudioEngine sharedEngine] playEffect:@"explosion_small.caf"];
                [enemy.shipLasers removeObject:laser];
                _ship.hp--;
                NSLog(@">>>>>>>>%d",_ship.hp);
                
            }
    }
    //Add win/Lose
    if (_ship.hp <= 0) {
        [_ship stopAllActions];
        _ship.visible = FALSE;
        [self endScene:kEndReasonLose];
    } 
    if (_ship.score == 10 && isMeetEnemy == kNormal)
    {
        isMeetEnemy = kMeetEnemy;
    }
    if(isMeetEnemy == kMeetEnemy)
    {
        [self addEnemy];
        isMeetEnemy = kHaveEnemy;
    }
    
    if(isMeetEnemy == kHaveEnemy && enemy.hp <=0)
    {
        [self addEffect:enemy.position];
//        [self addExplosion:enemy.position];
        enemy.visible = NO;
         [self endScene:kEndReasonWin];
    }
    

}

// on "init" you need to initialize your instance
-(id) init
{
	if( (self=[super init])) {
        
        //Add ship
		_batchNode = [CCSpriteBatchNode batchNodeWithFile:@"Sprites.pvr.ccz"];

        [self addChild:_batchNode];
        [[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:@"Sprites.plist"];
        
        _ship = [Player spriteWithSpriteFrameName:@"SpaceFlier_sm_1.png"];
        
        NSMutableArray *walkAnimFrames = [NSMutableArray array];
        for(int i = 1; i <= 2; ++i) {
            [walkAnimFrames addObject:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:[NSString stringWithFormat:@"SpaceFlier_sm_%d.png", i]]];
        }
        CCAnimation *walkAnim = [CCAnimation animationWithFrames:walkAnimFrames delay:0.1f];
        [_ship runAction:[CCRepeatForever actionWithAction:[CCAnimate actionWithAnimation:walkAnim restoreOriginalFrame:NO]]];
        
        CGSize winSize = [[CCDirector sharedDirector] winSize];
        _ship.position = ccp(winSize.width * 0.1, winSize.height * 0.5);
        [_batchNode addChild:_ship];
        
        // 1) Create the CCParallaxNode
        _backgroundNode = [CCParallaxNode node];
        [self addChild:_backgroundNode z:-1];
        
        // 2) Create the sprites we'll add to the CCParallaxNode
        _spacedust1 = [CCSprite spriteWithFile:@"bg_front_spacedust.png"];
        _spacedust2 = [CCSprite spriteWithFile:@"bg_front_spacedust.png"];
        _planetsunrise = [CCSprite spriteWithFile:@"bg_planetsunrise.png"];
        _galaxy = [CCSprite spriteWithFile:@"bg_galaxy.png"];
        _spacialanomaly = [CCSprite spriteWithFile:@"bg_spacialanomaly.png"];
        _spacialanomaly2 = [CCSprite spriteWithFile:@"bg_spacialanomaly2.png"];
        
        // 3) Determine relative movement speeds for space dust and background
        CGPoint dustSpeed = ccp(0.1, 0.1);
        CGPoint bgSpeed = ccp(0.05, 0.05);
	
        // 4) Add children to CCParallaxNode
        [_backgroundNode addChild:_spacedust1 
                                z:0 
                    parallaxRatio:dustSpeed 
                   positionOffset:ccp(0,winSize.height/2)];
        
        [_backgroundNode addChild:_spacedust2 
                                z:0 
                    parallaxRatio:dustSpeed 
                   positionOffset:ccp(_spacedust1.contentSize.width,winSize.height/2)];  
        
        [_backgroundNode addChild:_galaxy 
                                z:-1 
                    parallaxRatio:bgSpeed 
                   positionOffset:ccp(0,winSize.height * 0.7)];
        
        [_backgroundNode addChild:_planetsunrise 
                                z:-1 
                    parallaxRatio:bgSpeed 
                   positionOffset:ccp(600,winSize.height * 0)]; 
        
        [_backgroundNode addChild:_spacialanomaly 
                                z:-1 
                    parallaxRatio:bgSpeed 
                   positionOffset:ccp(900,winSize.height * 0.3)];   
        
        [_backgroundNode addChild:_spacialanomaly2 
                                z:-1 
                    parallaxRatio:bgSpeed 
                   positionOffset:ccp(1500,winSize.height * 0.9)];
        
        NSArray *starsArray = [NSArray arrayWithObjects:@"Stars1.plist", @"Stars2.plist", @"Stars3.plist", nil];
        for(NSString *stars in starsArray) {        
            CCParticleSystemQuad *starsEffect = [CCParticleSystemQuad particleWithFile:stars];        
            [self addChild:starsEffect z:1];
        }
        
        //AccelerometerEnabled 
        self.isAccelerometerEnabled = YES;
        
        //Add asteroids
        _asteroids = [[CCArray alloc] initWithCapacity:kNumAsteroids];
        for(int i = 0; i < kNumAsteroids; ++i) {
            CCSprite *asteroid = [CCSprite spriteWithSpriteFrameName:@"asteroid.png"];
            asteroid.visible = NO;
            [_batchNode addChild:asteroid];
            [_asteroids addObject:asteroid];
        }
        //Shooting Lasers
        _shipLasers = [[CCArray alloc] initWithCapacity:kNumLasers];
        for(int i = 0; i < kNumLasers; ++i) {
            CCSprite *shipLaser = [CCSprite spriteWithSpriteFrameName:@"laserbeam_blue.png"];
            shipLaser.visible = NO;
            [_batchNode addChild:shipLaser];
            [_shipLasers addObject:shipLaser];
        }
        
        self.isTouchEnabled = YES;
        
        //Win/Lose Detection               
        
        [[SimpleAudioEngine sharedEngine] playBackgroundMusic:@"SpaceGame.caf" loop:YES];
        [[SimpleAudioEngine sharedEngine] preloadEffect:@"explosion_large.caf"];
        [[SimpleAudioEngine sharedEngine] preloadEffect:@"laser_ship.caf"];
        [self scheduleUpdate];  
        
        isMeetEnemy = kNormal;
    }
	return self;
}

-(void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
    [[SimpleAudioEngine sharedEngine] playEffect:@"laser_ship.caf"];
    CGSize winSize = [CCDirector sharedDirector].winSize;
    
    CCSprite *shipLaser = [_shipLasers objectAtIndex:_nextShipLaser];
    _nextShipLaser++;
    if (_nextShipLaser >= _shipLasers.count) _nextShipLaser = 0;
    
    shipLaser.position = ccpAdd(_ship.position, ccp(shipLaser.contentSize.width/2, 0));
    shipLaser.visible = YES;
    [shipLaser stopAllActions];
    [shipLaser runAction:[CCSequence actions:
                          [CCMoveBy actionWithDuration:0.5 position:ccp(winSize.width, 0)],
                          [CCCallFuncN actionWithTarget:self selector:@selector(setInvisible:)],
                          nil]];
    
    if(isMeetEnemy == kHaveEnemy)
    {
    [enemy shoot];
    
    //Random position Enemy
    [enemy moveAroundPosition:_ship.position];
    }
    
}

// on "dealloc" you need to release all your retained objects
- (void) dealloc
{
    _ship = nil;
    
	[super dealloc];
}
@end
